home *** CD-ROM | disk | FTP | other *** search
- /* PSDGeomProcs.c */
- /* Here are the Quickdraw plug-in procs which handle the comparatively
- simple geometric stuff */
- /* Copyright 1992, Gary D. McGath */
-
- #include "psd.h"
-
- extern int thePSFile; /* ID of file to output to */
-
-
- pascal void psdRectProc(GrafVerb verb, Rect *theRect);
- pascal psdOvalProc(GrafVerb verb, Rect *theRect);
- pascal psdrRectProc(GrafVerb verb, Rect *theRect, short ovalwidth, short ovalheight);
- pascal psdLineProc(Point newPt);
- pascal psdPolyProc(GrafVerb verb, PolyHandle thePoly);
- pascal psdArcProc(GrafVerb verb, Rect *theRect, short startAngle, short arcAngle);
- void psdDrawLine(Point oldPt, Point newPt);
- void psdWriteRect(Rect *theRect);
- void psdDrawLine(Point oldPt, Point newPt);
-
-
-
- /* psdRectProc -- one of the easiest (ha!) */
- /* Should support non-square pen size at least for lines and rectangles */
- pascal void psdRectProc(GrafVerb verb, Rect *theRect)
- {
- /* First need to check for state changes and output needed code */
- if (thePort->pnVis < 0)
- return; /* nothing to draw */
-
- switch(verb) {
- case frame:
-
- if (thePort->pnSize.h == 0 && thePort->pnSize.v == 0)
- return;
- psdSetPenPat(); /* update gray level to pen pattern */
- psdWriteRect(theRect);
- OutputNum(thePort->pnSize.h,thePSFile); /* thickness of vertical strokes */
- OutputNum(thePort->pnSize.v,thePSFile); /* thickness of horizontal strokes */
- OutputString("frrec\r",thePSFile);
- break;
-
- case fill:
- case paint: /* to paint is to fill with the paint color & pattern */
- case erase: /* like paint, but background color & no pattern */
-
- if (verb == paint)
- psdSetPenPat(); /* update gray level to pen pattern */
- else if (verb == erase)
- OutputGray(0);
- else psdSetFillPat(); /* or fill pattern, if doing fill */
- psdWriteRect(theRect);
- OutputString("flrec\r",thePSFile);
- break;
-
- case invert:
- break; /* invert isn't supported */
-
- }
- }
-
- /* psdOvalProc -- draw an oval. PostScript knows about circles but not
- ellipses, so we have to scale the circular path (but *not* the stroking
- of it) to an ellipse. For the present, we assume that the pen is square
- (equal in horizontal and vertical dimensions). */
- pascal psdOvalProc(GrafVerb verb, Rect *theRect)
- {
- if (thePort->pnVis < 0)
- return; /* nothing to draw */
-
- switch(verb) {
- case frame:
-
- if (thePort->pnSize.h == 0 && thePort->pnSize.v == 0)
- return;
- psdSetPenPat(); /* update gray level to pen pattern */
- psdWriteRect(theRect);
- OutputNum(thePort->pnSize.h,thePSFile); /* thickness of vertical strokes */
- OutputString("froval\r",thePSFile);
- break;
-
- case fill:
- case paint:
- case erase:
-
- if (verb == paint)
- psdSetPenPat(); /* update gray level to pen pattern */
- else if (verb == erase)
- OutputGray(0);
- else psdSetFillPat(); /* or fill pattern, if doing fill */
- psdWriteRect(theRect);
- OutputString("floval\r",thePSFile);
- break;
-
- case invert:
- break; /* invert isn't supported */
- }
- }
-
-
- /* psdRRectProc -- draw a round-cornered rectangle. In this case, we make
- two simplifying assumptions: that the pen is square and that the corners
- are circular (width = height). */
- pascal psdrRectProc(GrafVerb verb, Rect *theRect, short ovalwidth,
- short ovalheight)
- {
- if (thePort->pnVis < 0)
- return; /* nothing to draw */
-
- switch(verb) {
- case frame:
-
- psdSetPenPat(); /* update gray level to pen pattern */
- psdWriteRect(theRect);
- OutputNum(thePort->pnSize.h,thePSFile); /* thickness of vertical strokes */
- OutputDouble(ovalwidth/2.0,thePSFile); /* oval radius */
- OutputString("frrrect\r",thePSFile);
- break;
-
- case fill:
- case paint:
- case erase:
-
- if (verb == paint)
- psdSetPenPat(); /* update gray level to pen pattern */
- else if (verb == erase)
- OutputGray(0);
- else psdSetFillPat(); /* or fill pattern, if doing fill */
- psdWriteRect(theRect);
- OutputDouble(ovalwidth/2.0,thePSFile); /* oval radius */
- OutputString("flrrect\r",thePSFile);
- break;
-
- case invert:
- break; /* invert isn't supported */
- }
-
- }
-
-
- /* psdLineProc -- draw a line from the current point to the new point.
- "Lines" in Quickdraw are actually funny-shaped polygons. */
- pascal psdLineProc(Point newPt)
- {
- Point oldPt;
- oldPt = thePort->pnLoc;
- thePort->pnLoc = newPt;
- if (thePort->pnVis < 0 || (thePort->pnSize.h == 0 && thePort->pnSize.v == 0)) {
- return; /* nothing to draw */
- }
- psdSetPenPat(); /* update gray level to pen pattern */
- psdDrawLine(oldPt, newPt);
- }
-
-
-
- pascal psdPolyProc(GrafVerb verb, PolyHandle thePoly)
- {
- int npoints;
- register int i;
- PolyPtr thePolyp;
- Point prevPoint;
-
- HLock(thePoly);
- thePolyp = *thePoly;
- npoints = (thePolyp->polySize - 10) / 4;
- switch(verb) {
- case frame:
- if (thePort->pnSize.h == 0 && thePort->pnSize.v == 0)
- return;
- psdSetPenPat();
- prevPoint = thePolyp->polyPoints[0];
- for (i = 1; i < npoints; i++) {
- psdDrawLine(prevPoint,thePolyp->polyPoints[i]);
- prevPoint = thePolyp->polyPoints[i];
- }
- break;
-
- case fill:
- case paint:
- case erase:
- if (verb == fill)
- psdSetFillPat();
- else if (verb == erase)
- OutputGray(0);
- else psdSetPenPat();
- prevPoint = thePolyp->polyPoints[0];
- OutputNum(prevPoint.h, thePSFile);
- OutputNum(prevPoint.v, thePSFile);
- OutputString("moveto ", thePSFile);
- for (i = 1; i < npoints; i++) {
- prevPoint = thePolyp->polyPoints[i];
- OutputNum(prevPoint.h, thePSFile);
- OutputNum(prevPoint.v, thePSFile);
- OutputString("lineto ", thePSFile);
- }
- OutputString("closepath fill\r", thePSFile);
- break;
- case invert:
- break; /* invert isn't supported */
-
- }
- HUnlock(thePoly);
- }
-
- pascal psdArcProc(GrafVerb verb, Rect *theRect, short startAngle, short arcAngle)
- {
- if (thePort->pnVis < 0)
- return; /* nothing to draw */
-
- if (arcAngle < 0) { /* make angle always positive */
- startAngle += arcAngle;
- arcAngle = -arcAngle;
- }
- switch(verb) {
- case frame:
-
- if (thePort->pnSize.h == 0 && thePort->pnSize.v == 0)
- return;
- psdSetPenPat(); /* update gray level to pen pattern */
- psdWriteRect(theRect);
- OutputNum(thePort->pnSize.h,thePSFile); /* thickness of vertical strokes */
- OutputNum(startAngle,thePSFile);
- OutputNum(arcAngle,thePSFile);
- OutputString("frarc\r",thePSFile);
- break;
-
- case fill:
- case paint:
- case erase:
-
- if (verb == paint)
- psdSetPenPat(); /* update gray level to pen pattern */
- else if (verb == erase)
- OutputGray(0);
- else psdSetFillPat(); /* or fill pattern, if doing fill */
- psdWriteRect(theRect);
- OutputDouble(startAngle,thePSFile);
- OutputDouble(arcAngle,thePSFile);
- OutputString("flarc\r",thePSFile);
- break;
-
- case invert:
- break; /* invert isn't supported */
- }
-
-
- }
-
-
- /* psdWriteRect -- output the coordinates of a rectangle. */
- void psdWriteRect(Rect *theRect)
- {
- OutputNum(theRect->left,thePSFile);
- OutputNum(theRect->top,thePSFile);
- OutputNum(theRect->right,thePSFile);
- OutputNum(theRect->bottom,thePSFile);
- }
-
- /* This subroutine is used for both lines and polygons */
- void psdDrawLine(Point oldPt, Point newPt)
- {
- int hdelta, vdelta;
- Point startcorner, endcorner;
-
- /* horizontal and vertical lines should really be special-cased
- for efficiency, but the general case works. */
- if (newPt.h > oldPt.h) {
- hdelta = thePort->pnSize.h;
- startcorner.h = oldPt.h;
- endcorner.h = newPt.h + hdelta;
- if (newPt.v > oldPt.v) {
- vdelta = thePort->pnSize.v;
- startcorner.v = oldPt.v;
- endcorner.v = newPt.v + vdelta;
- }
- else { /* newPt.v <= oldPt.v */
- vdelta = -thePort->pnSize.v;
- startcorner.v = oldPt.v - vdelta;
- endcorner.v = newPt.v;
- }
- }
- else { /* newPt.h <= oldPt.h */
- hdelta = -thePort->pnSize.h;
- startcorner.h = oldPt.h - hdelta;
- endcorner.h = newPt.h;
- if (newPt.v > oldPt.v) {
- vdelta = thePort->pnSize.v;
- startcorner.v = oldPt.v;
- endcorner.v = newPt.v + vdelta;
- }
- else { /* newPt.v <= oldPt.v */
- hdelta = -thePort->pnSize.h;
- vdelta = -thePort->pnSize.v;
- startcorner.v = oldPt.v - vdelta;
- endcorner.v = newPt.v;
- }
- }
- OutputNum(startcorner.h,thePSFile);
- OutputNum(startcorner.v,thePSFile);
- OutputString("moveto ",thePSFile);
- OutputNum(hdelta,thePSFile);
- OutputNum(0,thePSFile);
- OutputString("rlineto ",thePSFile);
- OutputNum(endcorner.h,thePSFile);
- OutputNum(endcorner.v - vdelta,thePSFile);
- OutputString("lineto ",thePSFile);
- OutputNum(0,thePSFile);
- OutputNum(vdelta,thePSFile);
- OutputString("rlineto ",thePSFile);
- OutputNum(-hdelta,thePSFile);
- OutputNum(0,thePSFile);
- OutputString("rlineto ",thePSFile);
- OutputNum(startcorner.h,thePSFile);
- OutputNum(startcorner.v+vdelta,thePSFile);
- OutputString("lineto closepath fill\r",thePSFile);
- }
-
-
-
-